﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using IndicoInterface;
using System.IO;
using DeepTalkDBServiceTest.DTDBService;
using System.ServiceModel;

namespace DeepTalkDBServiceTest
{
    /// <summary>
    /// Summary description for t_ConferenceStatus
    /// </summary>
    [TestClass]
    public class t_ConferenceStatus
    {
        public t_ConferenceStatus()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestInitialize]
        public void InitTest()
        {
            Utils.StartMainService();
            FileInfo db = new FileInfo("ConfData_" + TestContext.TestName + ".sdf");
            File.Copy(@"..\..\..\DeepTalkDBService\ConferenceData.sdf", db.FullName);
            using (DTDBClient rc = new DTDBClient())
            {
                rc.SetDBFile(db);
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            Utils.ShutdownMainService();
        }

        [TestMethod]
        public void TestConferencePresent()
        {
            /// Make sure we correctly return an ID for a talk - and that "FindTalk" works...
            
            AgendaInfo info = new AgendaInfo("http://indico.cern.ch/conferenceDisplay.py?showSession=all&showDate=all&view=xml&fr=no&confId=a042880");
            StringWriter sr = new StringWriter();
            info.Seralize(sr);

            using (DTDBClient rc = new DTDBClient())
            {
                int id = rc.FindTalk(sr.ToString());
                Assert.IsTrue(id == -1, "Talk was found in the database, huh?");

                rc.SubmitNewTalk(sr.ToString(), "This is a Title", DateTime.Now);

                id = rc.FindTalk(sr.ToString());
                Assert.IsTrue(id >= 0, "Talk was not in the DB - it should have been!");
            }
        }

        [TestMethod]
        public void TestXMLComesBackCorrectly()
        {
            AgendaInfo info = new AgendaInfo("http://indico.cern.ch/conferenceDisplay.py?showSession=all&showDate=all&view=xml&fr=no&confId=a042880");
            StringWriter sr = new StringWriter();
            info.Seralize(sr);

            using (var rc = new DTDBClient())
            {
                rc.SubmitNewTalk(sr.ToString(), "this is a title", DateTime.Now);

                var id = rc.FindTalk(sr.ToString());

                Assert.AreEqual(sr.ToString(), rc.GetTalkXML(id), "The XML didn't come back correctly!");
            }
        }

        [TestMethod]
        public void TestTimeToRenderCallback()
        {
            AgendaInfo info = new AgendaInfo("http://indico.cern.ch/conferenceDisplay.py?showSession=all&showDate=all&view=xml&fr=no&confId=a042880");
            StringWriter sr = new StringWriter();
            info.Seralize(sr);

            using (var rc = new DTDBClient())
            {
                rc.SubmitNewTalk(sr.ToString(), "this is a title", DateTime.Now);
                var id = rc.FindTalk(sr.ToString());

                var date = rc.GetNextUpdateTime(id);
                Assert.IsTrue(date.HasValue, "The date should have a value!");
                double delta = (DateTime.Now - date.Value).TotalSeconds;
                Assert.IsTrue(delta < 5, "The time isn't right (" + delta + ")!");
            }
        }

        [TestMethod]
        public void TestTalkIDIsValid()
        {
            AgendaInfo info = new AgendaInfo("http://indico.cern.ch/conferenceDisplay.py?showSession=all&showDate=all&view=xml&fr=no&confId=a042880");
            StringWriter sr = new StringWriter();
            info.Seralize(sr);

            using (DTDBClient rc = new DTDBClient())
            {
                rc.SubmitNewTalk(sr.ToString(), "This is a Title", DateTime.Now);
                Assert.IsTrue(rc.ValidTalkID(1), "Talk should be valid");
                Assert.IsFalse(rc.ValidTalkID(100), "Talk should not be valid!");
            }
        }

        [TestMethod]
        public void TestRemoveTalk()
        {
            string t1 = Utils.GetTalkXML("a1234");
            string t2 = Utils.GetTalkXML("a2345");
            using (DTDBClient rc = new DTDBClient())
            {
                rc.SubmitNewTalk(t1, "This is a Title", DateTime.Now);
                rc.SubmitNewTalk(t2, "This is a Title2", DateTime.Now);
                int id1 = rc.FindTalk(t1);
                int id2 = rc.FindTalk(t2);
                Assert.AreNotEqual(id1, id2, "The two talks should not be the same! Ack!");

                Assert.IsTrue(rc.ValidTalkID(id1), "Talk 1 should be valid");
                Assert.IsTrue(rc.ValidTalkID(id2), "Talk 2 should be valid");

                /// Make sure removal does removal.
                rc.RemoveTalk(id1);
                Assert.IsFalse(rc.ValidTalkID(id1), "Talk 1 should be gone");
                Assert.IsTrue(rc.ValidTalkID(id2), "Talk 2 should be valid");

                /// Make sure quiet fail and don't change anything else!
                rc.RemoveTalk(1201);
                Assert.IsFalse(rc.ValidTalkID(id1), "Talk 1 should be gone");
                Assert.IsTrue(rc.ValidTalkID(id2), "Talk 2 should be valid");
            }
        }
    }
}
